package be.rivendale.renderer.mk2.data;

import be.rivendale.mathematics.MathematicalUtilities;

import java.util.ArrayList;
import java.util.List;

public class Frame {
    private static final int APPROXIMATE_REGION_DIMENSIONS = 50;

    private RenderContext renderContext = RenderContext.getInstance();

    public List<Rectangle> createSegments() {
        int screenRegionWidth = calculateClosestDivisorTo(APPROXIMATE_REGION_DIMENSIONS, renderContext.getRenderInformation().getHorizontalCameraResolution());
        int screenRegionHeight = calculateClosestDivisorTo(APPROXIMATE_REGION_DIMENSIONS, renderContext.getRenderInformation().getVerticalCameraResolution());

        List<Rectangle> rectangles = new ArrayList<Rectangle>();
        for(int x = 0; x < renderContext.getRenderInformation().getHorizontalCameraResolution() / screenRegionWidth; x++) {
            for(int y = 0; y < renderContext.getRenderInformation().getVerticalCameraResolution() / screenRegionHeight; y++) {
                rectangles.add(new Rectangle(x * screenRegionWidth, y * screenRegionHeight, screenRegionWidth, screenRegionHeight));
            }
        }
        return rectangles;
    }

    private int calculateClosestDivisorTo(int approximateSize, int dividend) {
        int smallestDelta = dividend;
        int closestApproximation = dividend;
        int upperBound = dividend;
        for(int divisor = 1; divisor < upperBound; divisor++) {
             if(MathematicalUtilities.isDivisorOf(divisor, dividend)) {
                int delta = difference(approximateSize, divisor);
                if(delta < smallestDelta) {
                    smallestDelta = delta;
                    closestApproximation = divisor;
                }

                int inverseDivisor = dividend / divisor;
                int inverseDelta = difference(approximateSize, inverseDivisor);
                if(inverseDelta < smallestDelta) {
                    smallestDelta = inverseDelta;
                    closestApproximation = inverseDivisor;
                }

                upperBound = inverseDivisor;
            }
        }

        System.out.println("Closest approximation = " + closestApproximation + "(with a delta of " + smallestDelta + ")");
        return closestApproximation;
    }

    private int difference(int approximateSize, int divisor) {
        return Math.abs(approximateSize - divisor);
    }
}
